--[[
采集模块业务逻辑总入口
接口列表：
collectStart   开始采集
collectFinish  采集完成
--]]
local Log = require("common.Log")
local Lang = require("common.Lang")
local Util = require("common.Util")
local ExcelMapConf = require("excel.Map")
local Map = require("core.Map")
local Msg = require("core.Msg")
local Obj = require("core.Obj")
local ObjCollect = require("core.ObjCollect")
local ObjHuman = require("core.ObjHuman")
local Timer = require("core.Timer")
local SceneEvent = require("core.SceneEvent")
local Status = require("scene.Status")
local CollectDefine = require("collect.CollectDefine")
local BagLogic = require("bag.BagLogic")
local DropLogic = require("monster.DropLogic")
local Buffer = require("buffer.Buffer")
local TaskCallbacks = require("task.TaskCallbacks")
local CopyCallback = require("copy.CallbackL")
local Copy = require("copy.CopyL")


function collectHumanStart(human, beCollectHuman)
	local map_id = Map.scene_id_to_map_id[human.scene_id]
	local collectTime = ExcelMapConf.scene[map_id].can_collect_revive
	if collectTime == 0 then return CollectDefine.COLLECT_START_FAIL_HUMAN_MAP end
	if 0 < beCollectHuman.db.hp then return CollectDefine.COLLECT_START_FAIL_HUMAN_ALIVE end

	Status.doHumanControlStatusChange(human, Status.HUMAN_STATUS_COLLECT, Lang.COLLECT_HUMAN_BEGIN)
	human.collectObjId = beCollectHuman.id
	human.collectObjUid = beCollectHuman.uid
	human.collectEnd = Timer.now + collectTime * 1000

	return CollectDefine.COLLECT_START_OK, "", collectTime
end

function collectStart(human, objID)
	-- 合法性判断
	local collect = Obj.objs[objID]
	if collect == nil then
		return CollectDefine.COLLECT_START_FAIL_NO_TARGET-- 采集物不存在
	end
	
	if collect.obj_type == Obj.TYPE_HUMAN then
		-- 采集人尸体复活
		return collectHumanStart(human, collect)
	end
	
	if collect.obj_type ~= Obj.TYPE_COLLECT then
		return CollectDefine.COLLECT_START_FAIL_NO_TARGET-- 采集物不存在
	end
	
	if collect.scene_id == nil or collect.collected == true then
		return CollectDefine.COLLECT_START_FAIL_DIE_TARGET-- 采集物已被采集
	end 

	local distLen = Util.dist(collect.x, collect.y, human.x, human.y)
	if distLen > CollectDefine.MAX_COLLECT_RADIUS then
		return CollectDefine.COLLECT_START_FAIL_DISTANCE-- 采集物距离过远
	end
	
	-- 采集条件判断
	local config = ObjCollect.getConfig(collect)
	if config.condition.lv then
		if human.db.lv < config.condition.lv then return CollectDefine.COLLECT_START_FAIL_CONDITION_LV end
	end

	if config.condition.item then
		for itemID, count in pairs(config.condition.item) do
			local bagItemCount = BagLogic.getItemCount(human, itemID)
			if bagItemCount < count then
	--			ShopHandler.showQuickBuy(human, itemID, count - bagItemCount)
				return CollectDefine.COLLECT_START_FAIL_CONDITION_ITEM
			end
		end
	end
	if config.condition.family then
		if human.familyUuid == "" then
			return CollectDefine.COLLECT_START_FAIL_CONDITION_FAMILY
		end
	end
	if config.condition.copyaim then
		local sceneID = human.scene_id
		local copyID = Copy.sceneID2CopyID[sceneID]
		local roomID = Copy.sceneID2Room[sceneID]
		if copyID == nil or roomID == nil then
			return CollectDefine.COLLECT_START_FAIL_CONDITION_COPYAIM 
		end
		local aimRecord = Aim.aimRoomStatus[roomID]
		if aimRecord == nil or aimRecord[config.condition.copyaim] == nil or aimRecord[config.condition.copyaim] == CopyDefine.AIM_STATUS_FINISHED then
			return CollectDefine.COLLECT_START_FAIL_CONDITION_COPYAIM 
		end
	end
	if config.onlyOnce > 0 then
		if collect.collectHuman and collect.collectHuman[human._id] then
			return CollectDefine.COLLECT_START_FAIL_SOU_HUN
		end
	end
	
	if not ObjCollect.isOwner(collect, human) then
		return CollectDefine.COLLECT_START_FAIL_OWNER
	end

	
	-- 状态变化
	Status.doHumanControlStatusChange(human, Status.HUMAN_STATUS_COLLECT, config.beginCollect)
	human.collectObjId = collect.id
	human.collectObjUid = collect.uid
	human.collectEnd = Timer.now + config.collectTime * 1000
	return CollectDefine.COLLECT_START_OK, config.beginCollect, config.collectTime
end

local function sendFinishMsg(human, objID, retCode, noCollect)
	local msgRet = Msg.gc.GC_COLLECT_FINISH
	msgRet.objID = objID
	msgRet.retCode = retCode
	msgRet.noCollect = noCollect or 0
	Msg.send(msgRet, human.fd)
end

-- 清除采集状态用的（采集失败还是要清除状态的，要不移动时就提示中断采集了。。）
function cleanCollectStatus(human)
	human.collectObjId = nil
	human.collectObjUid = nil
	human.collectEnd = nil
	Status.doHumanControlStatusChange(human, Status.HUMAN_STATUS_NORMAL)
end

function collectHumanFinish(human, beCollectHuman)
	if 0 < beCollectHuman.db.hp then
		cleanCollectStatus(human)
		return sendFinishMsg(human, beCollectHuman.id, CollectDefine.COLLECT_FINISH_FAIL_HUMAN_ALIVE)
	end
	
	local map_id = Map.scene_id_to_map_id[human.scene_id]
	local collectTime = ExcelMapConf.scene[map_id].can_collect_revive
	if collectTime == 0 then 
		return sendFinishMsg(human, beCollectHuman.id, CollectDefine.COLLECT_FINISH_FAIL_HUMAN_MAP)
	end
	
	if Timer.now + 1000 < human.collectEnd then
		cleanCollectStatus(human)
		return sendFinishMsg(human, beCollectHuman.id, CollectDefine.COLLECT_FINISH_FAIL_HUMAN_TIME)
	end
	
	if human.db.bmsl then
		human.db.bmsl.save_cnt = human.db.bmsl.save_cnt + 1
	end

	cleanCollectStatus(human)
	Status.doHumanControlStatusChange(human, Status.HUMAN_STATUS_NORMAL, Lang.COLLECT_HUMAN_FINISH)

	ObjHuman.setHp(beCollectHuman, 0x7fffffff)
	ObjHuman.setMp(beCollectHuman, 0x7fffffff)
	local mm = Msg.gc.GC_REVIVE
	mm.obj_id = beCollectHuman.id
	mm.hp = beCollectHuman.db.hp
	mm.type = 1
	Obj.sendArea(mm, beCollectHuman.scene_id, beCollectHuman.x, beCollectHuman.y)
	
	Log.write(Log.LOGID_OSS_COLLECT_REVIVE, human._id, human.account, human.name, beCollectHuman._id, beCollectHuman.name, map_id)

end

function collectFinish(human, objID)
	-- 合法性判断
	if human.collectObjId == nil or human.status ~= Status.HUMAN_STATUS_COLLECT then
		return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_INVALID)
	end
	
	if human.collectObjId ~= objID then
		return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_INVALID)
	end
	
	local collect = Obj.getObj(human.collectObjId, human.collectObjUid)
	if collect == nil or collect.scene_id == nil then
		cleanCollectStatus(human)
		return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_DIE_TARGET) -- 采集物已被采集
	end 
	
	if collect.obj_type == Obj.TYPE_HUMAN then
		collectHumanFinish(human, collect)
		return
	end
	
	if collect.collected == true then
		cleanCollectStatus(human)
		return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_DIE_TARGET) -- 采集物已被采集
	end

	local config = ObjCollect.getConfig(collect)
	if Timer.now + 1000 < human.collectEnd then
		return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_INVALID) -- 时间判断
	end
	
	if config.condition.item then
		for itemID, count in pairs(config.condition.item) do
			local bagItemCount = BagLogic.getItemCount(human, itemID)
			if bagItemCount < count then 
				cleanCollectStatus(human)
--				ShopHandler.showQuickBuy(human, itemID, count - bagItemCount)
				return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_ITEM)
			end
		end
	end
	if config.condition.family then
		if human.db.familyUuid == nil then
			cleanCollectStatus(human)
			return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_FAMILY)
		end
	end
	if config.condition.copyaim then
		local sceneID = human.scene_id
		local copyID = Copy.sceneID2CopyID[sceneID]
		local roomID = Copy.sceneID2Room[sceneID]
		if copyID == nil or roomID == nil then
			cleanCollectStatus(human)
			return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_COPYAIM)
		end
		local aimRecord = Aim.aimRoomStatus[roomID]
		if aimRecord == nil or aimRecord[config.condition.copyaim] == nil or aimRecord[config.condition.copyaim] == CopyDefine.AIM_STATUS_FINISHED then
			cleanCollectStatus(human)
			return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_COPYAIM) 
		end
	end

	if not ObjCollect.isOwner(collect, human) then
		return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_OWNER) 
	end

	if config.onlyOnce > 0 then
		if collect.collectHuman and collect.collectHuman[human.db._id] then
			return sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_FAIL_SOU_HUN) 
		end
		
		collect.collectHuman = collect.collectHuman or {}
		collect.collectHuman[human._id] = 1
	end

	-- 状态改变
	human.collectObjId = nil
	human.collectObjUid = nil
	human.collectEnd = nil
	Status.doHumanControlStatusChange(human, Status.HUMAN_STATUS_NORMAL, config.endCollect)

	-- 采集消耗
	if config.condition.item then
		for itemID, count in pairs(config.condition.item) do
			BagLogic.delItemsById(human, itemID, count, "collect")
		end
	end
	
	if config.onlyOnce > 0 then
		sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_OK, 1)
	else
		sendFinishMsg(human, objID, CollectDefine.COLLECT_FINISH_OK)
	end
	
	-- 采集奖励
	if config.exp > 0 then ObjHuman.addExp(human, config.exp) end
	
	-- 采集掉落
	DropLogic.onCollectFinish(collect, human)

	-- 场景事件回调
	if config.callback > 0 then 
		SceneEvent.data.x = collect.x
		SceneEvent.data.y = collect.y
		SceneEvent.doSceneEvent(collect.scene_id, config.callback)
	end
	 -- 副本回调
  if Copy.isCopyBySceneID(collect.scene_id) then 
    CopyCallback.onCollectDieCB(human, collect, collect.collect_id)
  end
	-- 采集完加buff
	if #config.buff > 0 then 
		for i = 1, #config.buff do
			Buffer.add(config.buff[i], human, human)
		end
	end
	if #config.buffEx > 0 then 
		local buffExIndex = math.random(1, #config.buffEx)
		Buffer.add(config.buffEx[buffExIndex], human, human)
	end

	-- 采集回调
	local team --= TeamLogic.getTeamByUuid(human.db._id)
	if team == nil then
		TaskCallbacks.taskCollectCB(human, collect, collect.collect_id) -- 任务回调
	else
		for index, memberInfo in ipairs(team) do
			local member = ObjHuman.onlineUuid[memberInfo.uuid]
			-- 任务回调
			if member and member.scene_id == collect.scene_id then 
				local dx = member.x - collect.x
				local dy = member.y - collect.y
				if -Obj.GRID_WIDTH < dx and dx < Obj.GRID_WIDTH and -Obj.GRID_HEIGHT < dy and dy < Obj.GRID_HEIGHT then
					TaskCallbacks.taskCollectCB(member, collect, collect.collect_id)
				end
			end
		end
	end
	

	-- 采集物处理
	--[[
	0 表示采集完不消失 并且可以继续采集
	1 采集完后立刻消失 一段时间后重新出现 可以重新采集
	2 采集完后立刻消失 不再重生
	3 采集完后状态改变 不可继续采集 一段时间后消失 不再重生
	4 采集完后状态改变 不可继续采集 不消失
	--]]
	
	print("after collect status:", config.status)
	
	if config.status == 0 then 
	
	elseif config.status == 1 then 
		collect.die = 1
		Obj.leaveScene(collect)
		ObjCollect.list_reborn[collect.id] = {reborn = Timer.now + config.flushTime * 1000 - 500, uid = collect.uid, area_id = collect.area_id}
	elseif config.status == 2 then
		collect.die = 1
		if Obj.getObj(collect.id, collect.uid) then
			ObjCollect.destroy(collect)
		end
	elseif config.status == 3 then
		collect.collected = true
		local msgNotify = Msg.gc.GC_COLLECT_COLLECTED_NOTIFY
		msgNotify.objID = collect.id
		msgNotify.bodyID = config.bodyID2
		msgNotify.bone = config.isBoneID2
		Obj.sendArea(msgNotify, collect.scene_id, collect.x, collect.y)
		ObjCollect.list_reborn[collect.id] = {reborn = Timer.now + config.flushTime * 1000 - 500, uid = collect.uid}
	elseif config.status == 4 then
		collect.collected = true
		local msgNotify = Msg.gc.GC_COLLECT_COLLECTED_NOTIFY
		msgNotify.objID = collect.id
		msgNotify.bodyID = config.bodyID2
		msgNotify.bone = config.isBoneID2
		Obj.sendArea(msgNotify, collect.scene_id, collect.x, collect.y)
	end	
end

function canQuery(human, objID)
	local collect = Obj.objs[objID]
	if collect == nil or collect.obj_type ~= Obj.TYPE_COLLECT then return end
	
	local msgRet = Msg.gc.GC_COLLECT_CAN_QUERY
	msgRet.objID = objID
	msgRet.canCollect = 1
	local config = ObjCollect.getConfig(collect)
	if config.onlyOnce > 0 then
		if collect.collectHuman and collect.collectHuman[human.db._id] then
			msgRet.canCollect = 0
		end
	end
	Msg.send(msgRet, human.fd)
end
